package com.file.parser;


import com.file.bo.*;
import com.file.constant.ErrorCode;
import com.file.util.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Slf4j
public class ChromeGjjAnyHtmlParser {

    public ResponseData<String> parseChromeGjjAnyHtmlToJson(String daId, String filePath) {
        log.info("parseChromeGjjAnyHtmlToJson started, daId:{}", daId);
        String json = null;

        try {
            if (filePath.contains("_baseInfo")) {
                ChromeGjjAnyBaseInfo baseInfo = parseBaseInfoHtml(filePath);
                json = JsonUtils.convertObjectToJson(baseInfo);
            } else if (filePath.contains("_jnjl")) {
                ChromeGjjAnyDetail detail = parseDetailHtml(filePath);
                json = JsonUtils.convertObjectToJson(detail);
            } else if (filePath.contains("_dkxq")) {
                ChromeGjjAnyLoanBasicInfo loanBasicInfo = parseLoanBasicInfo(filePath);
                json = JsonUtils.convertObjectToJson(loanBasicInfo);
            } else if (filePath.contains("_hkmx")) {
                ChromeGjjAnyRepaymentInfo repaymentInfo = parseRepaymentInfo(filePath);
                json = JsonUtils.convertObjectToJson(repaymentInfo);
            } else {
                throw new RuntimeException("the file name is not supported");
            }
        } catch (Exception e) {
            log.error("OnError|{}||{}|{}|{}|{}", ErrorCode.FILE_PARSE_EXCEPTION.getCode(), daId, "", "", "parseChromeGjjAnyHtmlToJson failed", e);
            return new ResponseData<String>(json, ErrorCode.FILE_PARSE_EXCEPTION.getCode(), ErrorCode.FILE_PARSE_EXCEPTION.getMsg());
        }

        log.info("parseChromeGjjAnyHtmlToJson completed, daId:{}, json:{}", daId, json);
        return new ResponseData<String>(json, ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg());
    }

    public ChromeGjjAnyRepaymentInfo parseRepaymentInfo(String filePath) throws IOException {
        File input = new File(filePath);
        Document doc = Jsoup.parse(input, "UTF-8");

        ChromeGjjAnyRepaymentInfo chromeGjjAnyRepaymentInfo = new ChromeGjjAnyRepaymentInfo();
        List<ChromeGjjAnyRepaymentInfo.RepaymentDetail> repaymentDetailList = new ArrayList<>();
        chromeGjjAnyRepaymentInfo.setRepaymentDetailList(repaymentDetailList);

        Elements elements = doc.select(".el-table__row");
        for (Element element : elements) {
            ChromeGjjAnyRepaymentInfo.RepaymentDetail repaymentDetail = new ChromeGjjAnyRepaymentInfo.RepaymentDetail();
            repaymentDetail.setSerialNumber(element.child(0).text());
            repaymentDetail.setTime(element.child(1).text());
            repaymentDetail.setRepaymentPeriod(element.child(2).text());
            repaymentDetail.setRepaymentAmount(element.child(3).text());
            repaymentDetail.setPrincipal(element.child(4).text());
            repaymentDetail.setInterest(element.child(5).text());
            repaymentDetail.setPenaltyInterest(element.child(6).text());
            repaymentDetailList.add(repaymentDetail);
        }

        return  chromeGjjAnyRepaymentInfo;
    }

    public ChromeGjjAnyLoanBasicInfo parseLoanBasicInfo(String filePath) throws IOException {
        File input = new File(filePath);
        Document doc = Jsoup.parse(input, "UTF-8");

        ChromeGjjAnyLoanBasicInfo chromeGjjAnyLoanBasicInfo = new ChromeGjjAnyLoanBasicInfo();
        ChromeGjjAnyLoanBasicInfo.RepaymentInfo repaymentInfo = new ChromeGjjAnyLoanBasicInfo.RepaymentInfo();
        chromeGjjAnyLoanBasicInfo.setRepaymentInfo(repaymentInfo);
        ChromeGjjAnyLoanBasicInfo.LoanInfo loanInfo = new ChromeGjjAnyLoanBasicInfo.LoanInfo();
        chromeGjjAnyLoanBasicInfo.setLoanInfo(loanInfo);
        ChromeGjjAnyLoanBasicInfo.ApplicantInfo applicantInfo = new ChromeGjjAnyLoanBasicInfo.ApplicantInfo();
        chromeGjjAnyLoanBasicInfo.setApplicantInfo(applicantInfo);
        ChromeGjjAnyLoanBasicInfo.HouseInfo houseInfo = new ChromeGjjAnyLoanBasicInfo.HouseInfo();
        chromeGjjAnyLoanBasicInfo.setHouseInfo(houseInfo);

        Elements repaymentInfoRowElements = doc.select(".title-detail-container");
        for (Element element : repaymentInfoRowElements) {
            switch (element.child(0).text()) {//NOSONAR
                case "本期应还(元)":
                    String currentRepaymentAmount = element.child(1).text();
                    repaymentInfo.setCurrentRepaymentAmount(currentRepaymentAmount);
                    break;
                case "贷款余额(元)":
                    String loanBalance = element.child(1).text();
                    repaymentInfo.setLoanBalance(loanBalance);
                    break;
                case "累计已还本金(元)":
                    String totalRepaidPrincipal = element.child(1).text();
                    repaymentInfo.setTotalRepaidPrincipal(totalRepaidPrincipal);
                    break;
                case "累计已还利息(元)":
                    String totalRepaidInterest = element.child(1).text();
                    repaymentInfo.setTotalRepaidInterest(totalRepaidInterest);
                    break;
                case "贷款总额(元)":
                    String totalLoanAmount = element.child(1).text();
                    repaymentInfo.setTotalLoanAmount(totalLoanAmount);
                    break;
            }
        }

        Elements loanInfoRowElements = doc.select(".loan-info-grid > .grid-item");
        for (Element element : loanInfoRowElements) {
            switch (element.child(0).text()) {//NOSONAR
                case "贷款账号":
                    String loanAccount = element.child(1).text();
                    loanInfo.setLoanAccount(loanAccount);
                    break;
                case "借款合同编号":
                    String loanContractNumber = element.child(1).text();
                    loanInfo.setLoanContractNumber(loanContractNumber);
                    break;
                case "贷款金额(元)":
                    String loanAmount = element.child(1).text();
                    loanInfo.setLoanAmount(loanAmount);
                    break;
                case "贷款余额(元)":
                    String currentLoanBalance = element.child(1).text();
                    loanInfo.setCurrentLoanBalance(currentLoanBalance);
                    break;
                case "贷款利息":
                    String loanInterest = element.child(1).text();
                    loanInfo.setLoanInterest(loanInterest);
                    break;
                case "还款方式":
                    String repaymentMethod = element.child(1).text();
                    loanInfo.setRepaymentMethod(repaymentMethod);
                    break;
                case "贷款期次":
                    String loanPeriod = element.child(1).text();
                    loanInfo.setLoanPeriod(loanPeriod);
                    break;
                case "约定放款日期":
                    String agreedDisbursementDate = element.child(1).text();
                    loanInfo.setAgreedDisbursementDate(agreedDisbursementDate);
                    break;
                case "约定到期日期":
                    String agreedMaturityDate = element.child(1).text();
                    loanInfo.setAgreedMaturityDate(agreedMaturityDate);
                    break;
            }
        }

        Elements applicantInfoRowElements = doc.select(".loan-applyinfo-grid > .grid-item");
        for (Element element : applicantInfoRowElements) {

            switch (element.child(0).text()) {//NOSONAR
                case "借款人姓名":
                    String borrowerName = element.child(1).text();
                    applicantInfo.setBorrowerName(borrowerName);
                    break;
                case "借款人证件号码":
                    String borrowerIdNumber = element.child(1).text();
                    applicantInfo.setBorrowerIdNumber(borrowerIdNumber);
                    break;
                case "共同借款人姓名":
                    String coBorrowerName = element.child(1).text();
                    applicantInfo.setCoBorrowerName(coBorrowerName);
                    break;
                case "共同借款人证件号码":
                    String coBorrowerIdNumber = element.child(1).text();
                    applicantInfo.setCoBorrowerIdNumber(coBorrowerIdNumber);
                    break;
            }
        }

        Elements houseInfoRowElements = doc.select(".loan-houseinfo-grid > .grid-item");
        for (Element element : houseInfoRowElements) {
            switch (element.child(0).text()) {//NOSONAR
                case "房屋类型":
                    String houseType = element.child(1).text();
                    houseInfo.setHouseType(houseType);
                    break;
                case "购房合同号":
                    String housePurchaseContractNumber = element.child(1).text();
                    houseInfo.setHousePurchaseContractNumber(housePurchaseContractNumber);
                    break;
                case "建筑面积":
                    String buildingArea = element.child(1).text();
                    houseInfo.setBuildingArea(buildingArea);
                    break;
                case "购房总价(元)":
                    String houseTotalPrice = element.child(1).text();
                    houseInfo.setHouseTotalPrice(houseTotalPrice);
                    break;
                case "房屋坐落":
                    String houseLocation = element.child(1).text();
                    houseInfo.setHouseLocation(houseLocation);
                    break;
            }
        }

        return chromeGjjAnyLoanBasicInfo;
    }

    // 缴存基本信息详情页
    public ChromeGjjAnyBaseInfo parseBaseInfoHtml(String filePath) throws IOException {
        File input = new File(filePath);
        Document doc = Jsoup.parse(input, "UTF-8");

        ChromeGjjAnyBaseInfo baseInfo = new ChromeGjjAnyBaseInfo();
        ChromeGjjAnyBaseInfo.PersonalInfo personalInfo = new ChromeGjjAnyBaseInfo.PersonalInfo();
        ChromeGjjAnyBaseInfo.DepositInfo depositInfo = new ChromeGjjAnyBaseInfo.DepositInfo();
        ChromeGjjAnyBaseInfo.CenterInfo centerInfo = new ChromeGjjAnyBaseInfo.CenterInfo();

        Elements rowElements = doc.select(".info-grid-item-sub");

        for (Element element : rowElements) {
            switch (element.child(0).text()) {//NOSONAR
                case "姓名":
                    String name = element.child(1).text();
                    personalInfo.setName(name);
                    break;
                case "证件类型":
                    String idType = element.child(1).text();
                    personalInfo.setIdType(idType);
                    break;
                case "证件号码":
                    String idNo = element.child(1).text();
                    personalInfo.setIdNo(idNo);
                    break;
                case "手机号码":
                    String phoneNumber = element.child(1).text();
                    personalInfo.setPhoneNumber(phoneNumber);
                    break;
                case "个人账号":
                    String personalAccount = element.child(1).text();
                    personalInfo.setPersonalAccount(personalAccount);
                    break;
                case "个人账户状态":
                    String personalAccountStatus = element.child(1).text();
                    personalInfo.setPersonalAccountStatus(personalAccountStatus);
                    break;
                case "个人账户余额":
                    String personalAccountBalance = element.child(1).text();
                    personalInfo.setPersonalAccountBalance(personalAccountBalance);
                    break;
                case "个人缴存基数":
                    String personalDepositBase = element.child(1).text();
                    depositInfo.setPersonalDepositBase(personalDepositBase);
                    break;
                case "单位缴存比例":
                    String companyDepositRatio = element.child(1).text();
                    depositInfo.setCompanyDepositRatio(companyDepositRatio);
                    break;
                case "个人缴存比例":
                    String personalDepositRatio = element.child(1).text();
                    depositInfo.setPersonalDepositRatio(personalDepositRatio);
                    break;
                case "单位月缴存额":
                    String companyMonthlyDeposit = element.child(1).text();
                    depositInfo.setCompanyMonthlyDeposit(companyMonthlyDeposit);
                    break;
                case "个人月缴存额":
                    String personalMonthlyDeposit = element.child(1).text();
                    depositInfo.setPersonalMonthlyDeposit(personalMonthlyDeposit);
                    break;
                case "中心名称":
                    String centerName = element.child(1).text();
                    centerInfo.setCenterName(centerName);
                    break;
                case "中心编号":
                    String centerNumber = element.child(1).text();
                    centerInfo.setCenterNumber(centerNumber);
                    break;
                case "单位名称":
                    String companyName = element.child(1).text();
                    centerInfo.setCompanyName(companyName);
                    break;
            }
        }

        baseInfo.setPersonalInfo(personalInfo);
        baseInfo.setDepositInfo(depositInfo);
        baseInfo.setCenterInfo(centerInfo);
        log.info("chromeGjjAnyBaseInfoHtml = {}", baseInfo.toString());

        return baseInfo;
    }

    // 缴存明细详情
    public ChromeGjjAnyDetail parseDetailHtml(String filePath) throws IOException {
        File input = new File(filePath);
        Document doc = Jsoup.parse(input, "UTF-8");

        ChromeGjjAnyDetail detail = new ChromeGjjAnyDetail();
        Element div0 = doc.select(".el-table__body-wrapper").first();
        Elements divChildren = div0.children();
        List<ChromeGjjAnyDetail.ChromeGjjAnyHtmlDetailInfo> list = new ArrayList<>();
        for (Element table : divChildren) {
            Elements rows = table.select("tr");

            for (Element row : rows) {
                Elements cells = row.select("th, td");
                if (Objects.nonNull(cells) && cells.size() > 0) { //NOSONAR
                    if (!StringUtils.equals(cells.get(0).text(), "序号")) {  //NOSONAR
                        ChromeGjjAnyDetail.ChromeGjjAnyHtmlDetailInfo detailInfo = new ChromeGjjAnyDetail.ChromeGjjAnyHtmlDetailInfo();
                        detailInfo.setSerialNum(cells.get(0).text());
                        detailInfo.setDateTime(cells.get(1).text());
                        detailInfo.setBusinessType(cells.get(2).text());
                        detailInfo.setDepositAmount(cells.get(3).text());
                        detailInfo.setDepositBalance(cells.get(4).text());
                        list.add(detailInfo);
                    }
                }

            }
        }

        detail.setList(list);
        log.info("chromeGjjAnyDetailHtml = {}", list.toString());
        return detail;
    }

    public static void main(String[] args) {
        String filePath = "D:\\data\\file\\chrome-gjj-any\\公积金N合一\\chrome-gjj-any_baseInfo.html";
        String json = null;
        ChromeGjjAnyHtmlParser chromeGjjAnyHtmlParser = new ChromeGjjAnyHtmlParser();
		json = chromeGjjAnyHtmlParser.parseChromeGjjAnyHtmlToJson("", filePath).getData();
		System.out.println(json);

		filePath = "D:\\data\\file\\chrome-gjj-any\\公积金N合一\\chrome-gjj-any_jnjl.html";
		json = chromeGjjAnyHtmlParser.parseChromeGjjAnyHtmlToJson("", filePath).getData();
		System.out.println(json);

        filePath = "D:\\data\\file\\chrome-gjj-any\\公积金N合一\\chrome-gjj-any_dkxq.html";
        json = chromeGjjAnyHtmlParser.parseChromeGjjAnyHtmlToJson("", filePath).getData();
        System.out.println(json);

        filePath = "D:\\data\\file\\chrome-gjj-any\\公积金N合一\\chrome-gjj-any_hkmx.html";
        json = chromeGjjAnyHtmlParser.parseChromeGjjAnyHtmlToJson("", filePath).getData();
        System.out.println(json);

    }

}
